package april;

/**
 * @author ：冯涛滔
 * @date ：Created in 2020-4-21 20:13
 * @description：
 * @modified By：
 * @version:
 */
public class April21 {
    public static void main(String[] args) {
        System.out.println(numberOfSubarrays2());
    }
    public static int numberOfSubarrays( ) {
        int[] nums = {2,2,2,1,2,2,1,2,2,2};
        int k = 2;
        if (nums == null || nums.length == 0 || nums.length < k) return 0;
        // 双指针
        int left = 0, right = 0;
        int count = 0; // 连续子数组中奇数的个数
        int res = 0;
        int preEven = 0; // 记录第一个奇数前面的偶数个数
        while (right < nums.length){
            // 连续子数组中奇数个数不够
            if (count < k){
                if (nums[right] % 2 != 0) count++;
                right++; // 移动右侧指针
            }
            // 连续子数组中奇数个数够了，看第一个奇数前面有多少个偶数
            if (count == k) {
                preEven = 0;
                while (count == k){
                    res++;
                    if (nums[left] % 2 != 0) count--;
                    left++;
                    preEven++;
                }
            } else res += preEven; // 每次遇到 right 为偶数的时候就进行累加 拨入前面有三个偶数后面每增加一个偶数就会增加4种排序方法 4 = 三个偶数+第一个奇数本身
        }
        return res;

    }
    /**
     * create by: 睚雪
     * description:
     * 1. 设置好左右指针 res count preNumber
     * 2. count 代表 当前这个组合里有多少个奇数
     * 3. preNumber 代表这个组合里第一个奇数前有多少和偶数+1 比如2221221这里pre是4 如果这一段后面每增加一个偶数就代表会多出pre个组合的可能
     * 后面是奇数就代表前面k个奇数的组合的可能都被计算完了所以要重新计算 pre
     * 4.循环数组 遇到奇数就count++ 每次将right向前推进一步
     * 5.当count==k时
     *  重置 preNumber 是因为每次进入到这里 第一个奇数的位置都会改变所以这个值不能复用
     *  1.我们计算当前的排列会有多少种可能 也就是res++这一步
     *  2. 我们计算第一个奇数前面有多少个偶数 并且将奇数也加上 pre++ 如果有三个偶数pre就等于4 是以因为要加上第一个奇数
     *  3. 当left指针指向第一个奇数时 我们将count--
     *  4. 推进left
     *  5. 退出循环
     * 6. 当count == k的循环走完之后我们会获得两个值一个 当前组合有多少种可能输入进返回值 res++ , 当前组合的preNumber 如果后面每增加一个偶数会多出多少种组合
     * 7. count !=k 有两种种情况
     *  1. 循环刚刚开始没有找到k个奇数 这时候 res和preNumber 都是0怎么计算都无所谓
     *  2. 已经找到了一个组合 并且该组合后面的数字不是奇数 这时 res的值无所谓 关键是 preNumber这个只代表了一个组合后面每增加一个偶数会增加的排列可能性 所以 res+=preNumber
     * create time: 2020-4-21 21:09
     * @params []
     * @return int
     */
    public static int numberOfSubarrays2( ) {

        int[] nums = {2,2,2,1,2,2,1,2,2,2};
        int k = 2;
        if (nums == null || nums.length == 0 || nums.length < k) return 0;
        // 双指针
       int res = 0;
       int left = 0;
       int right = 0;
       int count =0; // 当前序列里有多少个奇数
       int preNumber = 0;//第一个奇数前面的偶数的个数+1 这个1是第一个奇数
        while(right<nums.length){
            if(nums[right]%2!=0){
                count++;
            }
            right++;
            if(count==k){//如果凑够了奇数
                preNumber = 0; //每次都要重置
                while(count==k){
                    res++; //这里的res加1是在不预计后面会不会有更多组合的可能 的情况下 当前k个奇数可以组成多少种组合
                    preNumber++;
                    if(nums[left]%2!=0){
                        count--;
                    }
                    left++;
                }
            }else{
                res += preNumber;
            }
        }
        return res;
    }

}